package com.mrxuxu.common.util;

import com.mrxuxu.common.log.Log;
import net.sf.json.JSONObject;
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.WebApplicationContext;

import javax.activation.MimetypesFileTypeMap;
import javax.net.ssl.*;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

public class HttpUtils {

	private static ServletContext servletContext;

	static{
		WebApplicationContext webContext = ContextLoader.getCurrentWebApplicationContext();
		servletContext = webContext.getServletContext();
	}
	
	/**
	 * 回送信息 Method
	 * @param responseMsg 要回送的消息
	 * @param 'stateCode' 状态码 正常：200 异常：400
	 */
	public static void doPost(String responseMsg) {
		try {
			HttpServletResponse response=SysContext.getResponse();
			// 将请求、响应的编码均设置为UTF-8（防止中文乱码）
			response.setCharacterEncoding("utf-8");
			response.setContentType("application/json;charset=utf-8");
			response.setHeader("Cache-Control","no-cache");//HTTP 1.1
			response.setHeader("Pragma","no-cache");//HTTP 1.0
			response.setDateHeader("Expires", 0);
			PrintWriter writer = response.getWriter();
			writer.write(responseMsg);
			writer.flush();
			writer.close();
		} catch (Exception ex) {
			Log.logger.error("Error Message------>" + ex.getMessage());
		}
	}

	/**
	 * 失败信息回调
	 * @param return_msg 信息
	 * @param return_code 状态码 （常见） 0成功 -1失败 其它自定义
	 */
	public static void doPostInfo(String return_code,String return_msg,String return_data){

		JSONObject returnJson= new JSONObject();

		returnJson.put("return_code",return_code);
		returnJson.put("return_msg",return_msg);
		if(!StringSupport.isEmpty(return_data)){
			//不为空的时候返回数据
			returnJson.put("return_data",return_data);
		}
		doPost(returnJson.toString());
	}

	/**
	 * 发送内容 "application/json;charset=UTF-8"
	 * @param contentType
	 * @param text
	 */
	public static void render(String contentType, String text) {
		HttpServletResponse response = SysContext.getResponse();
		response.setContentType(contentType);
	    try {
	         response.getWriter().write(text);
	    } catch (IOException e) {
	         e.printStackTrace();
	    }
	 }


	/**
	 * JSON数据上传
	 * @param jsonStr
	 */
	public static void writeJSON(String jsonStr) {
	     render("application/json;charset=UTF-8", jsonStr);
     }

	/**
	 * 表单上传
	 * @param urlStr
	 * @param textMap
	 * @param fileMap
	 * @return
	 */
	public static String formUpload(String urlStr, Map<String, String> textMap,Map<String, String> fileMap) {
		String res = "";
		HttpURLConnection conn = null;
		String BOUNDARY = "---------------------------GENIUSABCD123456"; //boundary就是request头和上传文件内容的分隔符
		try {
			URL url = new URL(urlStr);
			conn = (HttpURLConnection)url.openConnection();
			conn.setConnectTimeout(5000);
			conn.setReadTimeout(30000);
			conn.setDoOutput(true);
			conn.setDoInput(true);
			conn.setUseCaches(false);
			conn.setRequestMethod("POST");
			conn.setRequestProperty("Connection", "Keep-Alive");
			conn.setRequestProperty("Content-Type","multipart/form-data; boundary=" + BOUNDARY);
			OutputStream out = new DataOutputStream(conn.getOutputStream());
			if (textMap != null) {
				StringBuffer strBuf = new StringBuffer();
				Iterator iter = textMap.entrySet().iterator();
				while (iter.hasNext()) {
					Entry entry = (Entry) iter.next();
					String inputName = (String) entry.getKey();
					String inputValue = (String) entry.getValue();
					if (inputValue == null) {
						continue;
					}
					strBuf.append("\r\n").append("--").append(BOUNDARY).append("\r\n");
					strBuf.append("Content-Disposition: form-data; name=\""+ inputName + "\"\r\n\r\n");
					strBuf.append(inputValue);
				}
				out.write(strBuf.toString().getBytes());
			}
			if (fileMap != null) {
				Iterator iter = fileMap.entrySet().iterator();
				while (iter.hasNext()) {
					Entry entry = (Entry) iter.next();
					String inputName = (String) entry.getKey();
					String inputValue = (String) entry.getValue();
					if (inputValue == null) {
						continue;
					}
					inputValue = servletContext.getRealPath("/"+inputValue);
					File file = new File(inputValue);
					String filename = file.getName();
					String contentType = new MimetypesFileTypeMap().getContentType(file);
					if (filename.endsWith(".jpg")) {
						contentType = "image/jpg";
					}
					if (contentType == null || contentType.equals("")) {
						contentType = "application/octet-stream";
					}
					StringBuffer strBuf = new StringBuffer();
					strBuf.append("\r\n").append("--").append(BOUNDARY).append("\r\n");
					strBuf.append("Content-Disposition: form-data; name=\""+ inputName + "\"; filename=\"" + filename+ "\"\r\n");
					strBuf.append("Content-Type:" + contentType + "\r\n\r\n");
					out.write(strBuf.toString().getBytes());
					DataInputStream in = new DataInputStream(new FileInputStream(file));
					int bytes = 0;
					byte[] bufferOut = new byte[1024];
					while ((bytes = in.read(bufferOut)) != -1) {
						out.write(bufferOut, 0, bytes);
					}
					in.close();
				}
			}
			byte[] endData = ("\r\n--" + BOUNDARY + "--\r\n").getBytes();
			out.write(endData);
			out.flush();
			out.close();
			// 读取返回数据
			StringBuffer strBuf = new StringBuffer();
			BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream(),"UTF-8"));
			String line = null;
			while ((line = reader.readLine()) != null) {
				strBuf.append(line).append("\n");
			}
			res = strBuf.toString();
			reader.close();
		} catch (Exception e) {
			throw new RuntimeException(e.getMessage());
		} finally {
			if (conn != null) {
				conn.disconnect();
			}
		}
		return res;
	}

	public static String postRequest(String urlStr,Object textMap,Map<String,String>...maps){
		String res = "";
		HttpURLConnection conn = null;
		try {
			URL url = new URL(urlStr);
			conn = (HttpURLConnection)url.openConnection();
			conn.setConnectTimeout(5000);
			conn.setDoOutput(true);
			conn.setDoInput(true);
			conn.setUseCaches(false);
			conn.setRequestMethod("POST");
			conn.setRequestProperty("Connection", "Keep-Alive");
			conn.setRequestProperty("Content-Type","application/json;charset=utf-8");
			if(maps!=null&&maps.length>0){
				Map<String,String> tempMap = null;		
				tempMap = maps[0];
				for(Entry<String,String> entry : tempMap.entrySet()){
					conn.setRequestProperty(entry.getKey(),entry.getValue());
				}
				
			}
			OutputStream out = new DataOutputStream(conn.getOutputStream());
			String paramStr = "{}";
			if(textMap!=null){
				paramStr = JsonUtil.jsonSerialization(textMap);
			}
			out.write(paramStr.getBytes("utf-8"));
			out.flush();
			out.close();
			
			StringBuffer strBuf = new StringBuffer();
			BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream(),"UTF-8"));
			String line = null;
			while ((line = reader.readLine()) != null) {
				strBuf.append(line).append("\n");
			}
			res = strBuf.toString();
			reader.close();
		}catch(Exception e){
			throw new RuntimeException(e.getMessage());
		} finally {
			if (conn != null) {
				conn.disconnect();
			}
		}
		return res;
	}
	
	public static String getRequest(String urlStr,Map<String,?>...maps){
		String res = "";
		HttpURLConnection conn = null;
		try {
			URL url = new URL(urlStr);
			conn = (HttpURLConnection)url.openConnection();
			conn.setConnectTimeout(5000);
			conn.setRequestMethod("GET");
			conn.setRequestProperty("Connection", "Keep-Alive");
			conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded;charset=utf-8");
			if(maps!=null&&maps.length>0){
				Map<String,?> tempMap = null;		
				tempMap = maps[0];
				for(Entry<String,?> entry : tempMap.entrySet()){
					conn.setRequestProperty(entry.getKey(),entry.getValue().toString());
				}
				
			}
			StringBuffer strBuf = new StringBuffer();
			BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream(),"UTF-8"));
			String line = null;
			while ((line = reader.readLine()) != null) {
				strBuf.append(line).append("\n");
			}
			res = strBuf.toString();
			reader.close();
		}catch(Exception e){
			throw new RuntimeException(e.getMessage());
		} finally {
			if (conn != null) {
				conn.disconnect();
			}
		}
		return res;
	}
	/**
	 * fbgetRequest
	 * @param urlStr
	 * @param maps
	 * @return
	 */
	public static String getRequestOveride(String urlStr,Map<String,Object>...maps){
		String res = "";
		HttpURLConnection conn = null;
		try {
			URL url = new URL(urlStr);
			conn = (HttpURLConnection)url.openConnection();
			conn.setConnectTimeout(5000);
			conn.setRequestMethod("GET");
			conn.setRequestProperty("Connection", "Keep-Alive");
			conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded;charset=utf-8");
			if(maps!=null&&maps.length>0){
				Map<String,Object> tempMap=null;
				tempMap = maps[0];
				for(Entry<String, Object> entry : tempMap.entrySet()){
					conn.setRequestProperty(entry.getKey(),(String) entry.getValue());
				}
				
			}
			
			StringBuffer strBuf = new StringBuffer();
			BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream(),"UTF-8"));
			String line = null;
			while ((line = reader.readLine()) != null) {
				strBuf.append(line).append("\n");
			}
			res = strBuf.toString();
			reader.close();
		}catch(Exception e){
			throw new RuntimeException(e.getMessage());
		} finally {
			if (conn != null) {
				conn.disconnect();
			}
		}
		
		return res;
	}
	
	public static String doPost(String url, String ctype, byte[] content) throws Exception {  
        HttpsURLConnection conn = null;  
        OutputStream out = null;  
        String rsp = null;  
        try {  
            try{  
                SSLContext ctx = SSLContext.getInstance("TLS");  
                ctx.init(new KeyManager[0], new TrustManager[] {new DefaultTrustManager()}, new SecureRandom());  
                SSLContext.setDefault(ctx);  
  
                conn = getConnection(new URL(url), "POST", ctype);   
                conn.setHostnameVerifier(new HostnameVerifier() {  
                    @Override  
                    public boolean verify(String hostname, SSLSession session) {  
                        return true;  
                    }
                });  
                conn.setConnectTimeout(5000);
            }catch(Exception e){
				Log.logger.error("GET_CONNECTOIN_ERROR, URL = " + url, e);
                throw e;  
            }  
            try{  
                out = conn.getOutputStream();  
                out.write(content);  
                rsp = getResponseAsString(conn);  
            }catch(IOException e){
				Log.logger.error("REQUEST_RESPONSE_ERROR, URL = " + url, e);
                throw e;  
            }
        }finally {  
            if (out != null) {  
                out.close();  
            }  
            if (conn != null) {  
                conn.disconnect();  
            }  
        }           
        return rsp;  
    }
	
	private static class DefaultTrustManager implements X509TrustManager {  
		  
        @Override  
        public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {}  
  
        @Override  
        public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {}  
  
        @Override  
        public X509Certificate[] getAcceptedIssuers() {  
            return null;  
        }  
    }
	
	private static HttpsURLConnection getConnection(URL url, String method, String ctype)throws IOException {
        HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();  
        conn.setRequestMethod(method);  
        conn.setDoInput(true);  
        conn.setDoOutput(true);  
        conn.setRequestProperty("Accept", "text/xml,text/javascript,text/html");  
        conn.setRequestProperty("User-Agent", "stargate");  
        conn.setRequestProperty("Content-Type", ctype);  
        return conn;  
	}
	
	protected static String getResponseAsString(HttpURLConnection conn) throws IOException {  
       String charset = "utf-8";
       InputStream es = conn.getErrorStream();  
       if (es == null) {  
           return getStreamAsString(conn.getInputStream(), charset);  
       } else {  
           String msg = getStreamAsString(es, charset);  
           if (StringSupport.isEmpty(msg)) {
               throw new IOException(conn.getResponseCode() + ":" + conn.getResponseMessage());  
           } else {  
               throw new IOException(msg);  
           }  
       }  
   }
	private static String getStreamAsString(InputStream stream, String charset) throws IOException {		
       try {  
           BufferedReader reader = new BufferedReader(new InputStreamReader(stream, charset));  
           StringWriter writer = new StringWriter();  

           char[] chars = new char[256];  
           int count = 0;  
           while ((count = reader.read(chars)) > 0) {  
               writer.write(chars, 0, count);  
           }  
 
           return writer.toString();  
       } finally {  
           if (stream != null) {  
               stream.close();  
           }  
       }  
   }
}